import type { TBody, TParams } from '@/types';
import { createConfig, getQueryParams, handleReqMiddleware } from '@/lib/api';
import type {
  ICheckOauthClient,
  IOauthClient,
  IOauthClientApi,
  IOauthClientStatistics,
  IOauthClientToken,
  IOauthClientUserInfo,
  IPagination,
  IToken,
} from '@/interfaces';

export const createOauthClient = (
  params: TBody<{
    name: string;
    website: string;
    callback: string;
  }>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'POST' });
  return fetch(config.baseURL + '/oauth/clients', config).then(
    handleReqMiddleware
  );
};

export const updateOauthClientApiByApiId = (
  params: TBody<{
    name?: string;
    overview?: string;
    category?: string;
    doc?: string;
    type?: 'DEFAULT' | 'REQUIRED';
    upperLimit?: number;
  }>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'PUT' });
  return fetch(
    config.baseURL + `/oauth/clients/apis/${config.id}`,
    config
  ).then(handleReqMiddleware);
};

export const updateOauthClientById = (
  params: TBody<{
    name?: string;
    overview?: string;
    logo?: string;
    website?: string;
    callback?: string;
  }>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'PUT' });
  return fetch(config.baseURL + `/oauth/clients/${config.id}`, config).then(
    handleReqMiddleware
  );
};

export const updateOauthClientStatus = (
  params: TBody<{
    status?: string;
    reviewStatus?: string;
    reviewReason?: string;
  }>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'PATCH' });
  return fetch(
    config.baseURL + `/oauth/clients/${config.id}/status`,
    config
  ).then(handleReqMiddleware);
};

export const updateOauthClientApiStatus = (
  params: TBody<{
    apiId: string;
    reviewStatus?: string;
    reviewReason?: string;
  }>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'PATCH' });
  return fetch(
    config.baseURL +
      `/oauth/clients/${config.id}/apis/${params.data!.apiId}/status`,
    config
  ).then(handleReqMiddleware);
};

export const updateOauthClientSecretById = (
  params: TBody<void>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'PATCH' });
  return fetch(
    config.baseURL + `/oauth/clients/${config.id}/secret`,
    config
  ).then(handleReqMiddleware);
};

export const checkOauthClient = (
  params: TBody<{
    responseType: string;
    clientId: string;
    redirectUri: string;
    scope: string;
  }>
): Promise<Response | ICheckOauthClient> => {
  const config = createConfig(params, { method: 'POST' });
  return fetch(config.baseURL + '/oauth/clients/check', config).then(
    handleReqMiddleware
  );
};

export const queryOauthClientById = (
  params?: TParams
): Promise<Response | IOauthClient> => {
  const config = createConfig(params);
  return fetch(config.baseURL + `/oauth/clients/${config.id}`, config).then(
    handleReqMiddleware
  );
};

export const queryOauthClientByClientId = (
  params?: TParams
): Promise<Response | IOauthClient> => {
  const config = createConfig(params);
  return fetch(config.baseURL + `/oauth/clients/${config.id}/by`, config).then(
    handleReqMiddleware
  );
};

export const queryOauthClientApis = (
  params?: TParams
): Promise<Response | IOauthClientApi[]> => {
  const config = createConfig(params);
  return fetch(
    config.baseURL + `/oauth/clients/apis?${getQueryParams(config)}`,
    config
  ).then(handleReqMiddleware);
};

export const queryOauthClientSecretById = (
  params?: TParams
): Promise<Response | string> => {
  const config = createConfig(params);
  return fetch(
    config.baseURL + `/oauth/clients/${config.id}/secret`,
    config
  ).then(handleReqMiddleware);
};

export const queryOauthClientsByUser = (
  params?: TParams
): Promise<Response | IOauthClient[]> => {
  const config = createConfig(params);
  return fetch(config.baseURL + '/oauth/clients/user', config).then(
    handleReqMiddleware
  );
};

export const queryAllOauthClient = (
  params?: TParams
): Promise<Response | IPagination<IOauthClient>> => {
  const config = createConfig(params);
  return fetch(
    config.baseURL + `/oauth/clients?${getQueryParams(config)}`,
    config
  ).then(handleReqMiddleware);
};

export const queryOauthClientStatistics = (
  params?: TParams
): Promise<Response | IOauthClientStatistics> => {
  const config = createConfig(params);
  return fetch(config.baseURL + '/oauth/clients/statistics', config).then(
    handleReqMiddleware
  );
};

export const applyOauthClientApi = (
  params: TBody<{
    apiId: string;
  }>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'PATCH' });
  return fetch(
    config.baseURL +
      `/oauth/clients/${config.id}/apis/${params.data!.apiId}/apply`,
    config
  ).then(handleReqMiddleware);
};

export const deleteOauthClient = (
  params: TBody<void>
): Promise<Response | void> => {
  const config = createConfig(params, { method: 'DELETE' });
  return fetch(config.baseURL + `/oauth/clients/${config.id}`, config).then(
    handleReqMiddleware
  );
};

export const oauthClientAuthCallback = (
  params: TBody<{
    code: string;
    state?: string;
    clientId: string;
  }>
): Promise<Response | IToken> => {
  const config = createConfig(params);
  return fetch(
    config.baseURL + `/oauth/clients/callback?${getQueryParams(config)}`,
    config
  ).then(handleReqMiddleware);
};

export const getOauthClientToken = (
  params: TBody<{
    grantType: string;
    clientId: string;
    clientSecret: string;
    redirectUri: string;
    code: string;
  }>
): Promise<Response | IOauthClientToken> => {
  const config = createConfig(params, { method: 'POST' });
  return fetch(config.baseURL + '/oauth/clients/token', config).then(
    handleReqMiddleware
  );
};

export const getOauthClientUserInfo = (
  params?: TParams
): Promise<Response | IOauthClientUserInfo> => {
  const config = createConfig(params);
  return fetch(config.baseURL + '/oauth/clients/user/info', config).then(
    handleReqMiddleware
  );
};
